<template>
  <div class="cell-render-content">
    <!-- Text Content -->
    <template v-if="textContent">
      <span :style="getTextContentStyle(textContent, !!dataValue)">
        {{ getTextDisplayValue(textContent, dataValue) }}
      </span>
    </template>

    <!-- Input Content -->
    <template v-else-if="inputContent">
      <el-input
        v-if="!inputContent.inputType || inputContent.inputType === 'text'"
        :model-value="modelValue"
        @update:modelValue="(val) => emit('update:modelValue', val)"
        :placeholder="inputContent.placeholder"
        :disabled="inputContent.disabled"
        :readonly="inputContent.readonly"
        size="small"
      />
      <el-input-number
        v-else-if="inputContent.inputType === 'number'"
        :model-value="modelValueAsNumber"
        @update:modelValue="(val) => emit('update:modelValue', val)"
        :placeholder="inputContent.placeholder"
        :disabled="inputContent.disabled"
        :readonly="inputContent.readonly"
        controls-position="right"
        size="small"
        style="width: 100%"
      />
      <el-date-picker
        v-else-if="inputContent.inputType === 'date'"
        :model-value="modelValue"
        @update:modelValue="(val) => emit('update:modelValue', val)"
        type="date"
        :placeholder="inputContent.placeholder"
        :disabled="inputContent.disabled"
        :readonly="inputContent.readonly"
        size="small"
        style="width: 100%"
      />
      <!-- Add other input types for El-Input as needed -->
    </template>

    <!-- Image Content -->
    <template v-else-if="imageContent">
      <el-image
        v-if="getImageSrc(imageContent, dataValue)"
        :src="getImageSrc(imageContent, dataValue)"
        fit="contain"
        style="max-width: 100%; max-height: 100px"
      >
        <template #error>
          <div class="image-slot">
            <el-icon><Picture /></el-icon>
          </div>
        </template>
      </el-image>
      <span v-else>[无图片]</span>
    </template>

    <!-- Fallback for unknown or unhandled types -->
    <template v-else>
      <span style="color: red">未知内容类型: {{ contentDef.type }}</span>
    </template>
  </div>
</template>

<script setup lang="ts">
import { PropType, computed, StyleValue } from 'vue';
import {
  ContentDefinition,
  TextContent,
  InputContent,
  ImageContent,
} from '@/models/content.model';
import { Picture } from '@element-plus/icons-vue'; // For image error slot

const props = defineProps({
  contentDef: { type: Object as PropType<ContentDefinition>, required: true },
  /**
   * The actual data value for this cell, resolved from formData and dataMetaModelField
   * For input types, this is used for v-model.
   * For text types, this is used if valueType is 'metaModel'.
   */
  dataValue: {
    type: [
      String,
      Number,
      Boolean,
      Date,
      Object,
      Array,
      undefined,
    ] as PropType<unknown>, // Changed from any to unknown
    default: undefined,
  },
  /**
   * For input types, v-model binding.
   */
  modelValue: {
    type: [
      String,
      Number,
      Boolean,
      Date,
      Object,
      Array,
      undefined,
    ] as PropType<unknown>, // Changed from any to unknown
    default: undefined,
  },
});

const emit = defineEmits(['update:modelValue']);

// Computed properties for content types
const textContent = computed(() =>
  props.contentDef.type === 'text'
    ? (props.contentDef as TextContent)
    : undefined
);
const inputContent = computed(() =>
  props.contentDef.type === 'input'
    ? (props.contentDef as InputContent)
    : undefined
);
const imageContent = computed(() =>
  props.contentDef.type === 'image'
    ? (props.contentDef as ImageContent)
    : undefined
);

// Computed property for modelValue in el-input-number
const modelValueAsNumber = computed(() => {
  if (typeof props.modelValue === 'number') {
    return props.modelValue;
  }
  return undefined;
});

// --- Text Content Helpers ---
function getTextDisplayValue(
  textContent: TextContent,
  boundDataValue: unknown // Changed from any to unknown
): string {
  if (textContent.valueType === 'static') {
    return textContent.staticText || '';
  }
  if (textContent.valueType === 'metaModel') {
    // boundDataValue is already the resolved value
    return boundDataValue !== undefined && boundDataValue !== null
      ? String(boundDataValue)
      : textContent.staticText || ''; // Fallback to staticText if data is null/undefined
  }
  if (textContent.valueType === 'predefined') {
    if (textContent.predefinedType === 'currentDate') {
      // Need to ensure boundDataValue is a Date if used here, though currently it's not used for currentDate
      return formatDate(new Date(), textContent.dateFormat);
    }
    return '未知预定义类型';
  }
  return '';
}

function getTextContentStyle(
  textContent: TextContent,
  hasBoundData: boolean
): StyleValue {
  if (textContent.valueType === 'metaModel' && !hasBoundData) {
    // If it's a metaModel field but no data is bound (e.g. placeholder in designer, or data is null)
    // and we want to show the field name as placeholder
    return { color: textContent.metaModelPlaceholderColor || '#999' };
  }
  return {};
}

// --- Image Content Helper ---
function getImageSrc(
  imageContent: ImageContent,
  boundDataValue: unknown // Changed from any to unknown
): string | undefined {
  if (imageContent.srcType === 'staticUrl') {
    return imageContent.staticUrl;
  }
  if (imageContent.srcType === 'metaModel') {
    // Need to ensure boundDataValue is a string if used here
    return boundDataValue !== undefined && boundDataValue !== null
      ? String(boundDataValue)
      : undefined; // Added null/undefined check
  }
  return undefined;
}

// --- General Helpers ---
function formatDate(date: Date, formatStr?: string): string {
  if (!formatStr) formatStr = 'YYYY-MM-DD HH:mm:ss';
  const M = date.getMonth() + 1;
  const D = date.getDate();
  const h = date.getHours();
  const m = date.getMinutes();
  const s = date.getSeconds();
  return formatStr
    .replace('YYYY', date.getFullYear().toString())
    .replace('MM', M < 10 ? '0' + M : M.toString())
    .replace('DD', D < 10 ? '0' + D : D.toString())
    .replace('HH', h < 10 ? '0' + h : h.toString())
    .replace('mm', m < 10 ? '0' + m : m.toString())
    .replace('ss', s < 10 ? '0' + s : s.toString());
}
</script>

<style scoped>
.cell-render-content {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center; /* Default vertical align */
  /* justify-content will be controlled by cell.style.textAlign */
}
.image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: var(--el-fill-color-light);
  color: var(--el-text-color-secondary);
  font-size: 20px;
}
.el-icon {
  font-size: inherit;
}
</style>
